<!DOCTYPE html>
<html lang=zh>
<head>
  <meta charset="utf-8">
  
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui">
  <meta name="renderer" content="webkit">
  <meta http-equiv="Cache-Control" content="no-transform" />
  <meta http-equiv="Cache-Control" content="no-siteapp" />
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black">
  <meta name="format-detection" content="telephone=no,email=no,adress=no">
  <!-- Color theme for statusbar -->
  <meta name="theme-color" content="#000000" />
  <!-- 强制页面在当前窗口以独立页面显示,防止别人在框架里调用页面 -->
  <meta http-equiv="window-target" content="_top" />
  
  
  <title>Vue八股文1-30 | Hexo</title>
  <meta name="description" content="1. 你怎么理解指令？工作中你封装过自定义指令吗？举一些例子1234指令本质上是对dom的操作，vue封装这些指令就是为了我们更为合理符合规范的操作dom，避免DOM滥操作。我们也可以自定义指令，自定义指令也是对DOM操作的封装，我之前工作中封装过一些自定义指令:(1)防抖指令(2)权限指令......  2. 计算属性能不能绑定在v-model上？1计算属性有setter方法时可以用v-mode">
<meta property="og:type" content="article">
<meta property="og:title" content="Vue八股文1-30">
<meta property="og:url" content="http://bear-peak.gitee.io/2022/12/26/Vue%E5%85%AB%E8%82%A1%E6%96%87(1-30)/index.html">
<meta property="og:site_name" content="Hexo">
<meta property="og:description" content="1. 你怎么理解指令？工作中你封装过自定义指令吗？举一些例子1234指令本质上是对dom的操作，vue封装这些指令就是为了我们更为合理符合规范的操作dom，避免DOM滥操作。我们也可以自定义指令，自定义指令也是对DOM操作的封装，我之前工作中封装过一些自定义指令:(1)防抖指令(2)权限指令......  2. 计算属性能不能绑定在v-model上？1计算属性有setter方法时可以用v-mode">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2022-12-26T12:43:43.699Z">
<meta property="article:modified_time" content="2022-12-26T13:09:00.259Z">
<meta property="article:author" content="John Doe">
<meta name="twitter:card" content="summary">
  <!-- Canonical links -->
  <link rel="canonical" href="http://bear-peak.gitee.io/2022/12/26/Vue%E5%85%AB%E8%82%A1%E6%96%87(1-30)/index.html">
  
    <link rel="alternate" href="/atom.xml" title="Hexo" type="application/atom+xml">
  
  
    <link rel="icon" href="/favicon.png" type="image/x-icon">
  
  
<link rel="stylesheet" href="/css/style.css">

  
  
  
  
<meta name="generator" content="Hexo 6.3.0"></head>


<body class="main-center" itemscope itemtype="http://schema.org/WebPage">
  <header class="header" itemscope itemtype="http://schema.org/WPHeader">
  <div class="slimContent">
    <div class="navbar-header">
      
      
      <div class="profile-block text-center">
        <a id="avatar" href="https://github.com/cofess" target="_blank">
          <img class="img-circle img-rotate" src="/images/avatar.jpg" width="200" height="200">
        </a>
        <h2 id="name" class="hidden-xs hidden-sm">熊峰</h2>
        <h3 id="title" class="hidden-xs hidden-sm hidden-md">Web Developer &amp; Designer</h3>
        <small id="location" class="text-muted hidden-xs hidden-sm"><i class="icon icon-map-marker"></i> Wuhan, China</small>
      </div>
      
      <div class="search" id="search-form-wrap">

    <form class="search-form sidebar-form">
        <div class="input-group">
            <input type="text" class="search-form-input form-control" placeholder="搜索" />
            <span class="input-group-btn">
                <button type="submit" class="search-form-submit btn btn-flat" onclick="return false;"><i class="icon icon-search"></i></button>
            </span>
        </div>
    </form>
    <div class="ins-search">
  <div class="ins-search-mask"></div>
  <div class="ins-search-container">
    <div class="ins-input-wrapper">
      <input type="text" class="ins-search-input" placeholder="想要查找什么..." x-webkit-speech />
      <button type="button" class="close ins-close ins-selectable" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
    </div>
    <div class="ins-section-wrapper">
      <div class="ins-section-container"></div>
    </div>
  </div>
</div>


</div>
      <button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target="#main-navbar" aria-controls="main-navbar" aria-expanded="false">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
    </div>
    <nav id="main-navbar" class="collapse navbar-collapse" itemscope itemtype="http://schema.org/SiteNavigationElement" role="navigation">
      <ul class="nav navbar-nav main-nav ">
        
        
        <li class="menu-item menu-item-home">
          <a href="/.">
            
            <i class="icon icon-home-fill"></i>
            
            <span class="menu-title">首页</span>
          </a>
        </li>
        
        
        <li class="menu-item menu-item-archives">
          <a href="/archives">
            
            <i class="icon icon-archives-fill"></i>
            
            <span class="menu-title">归档</span>
          </a>
        </li>
        
        
        <li class="menu-item menu-item-categories">
          <a href="/categories">
            
            <i class="icon icon-folder"></i>
            
            <span class="menu-title">分类</span>
          </a>
        </li>
        
        
        <li class="menu-item menu-item-tags">
          <a href="/tags">
            
            <i class="icon icon-tags"></i>
            
            <span class="menu-title">标签</span>
          </a>
        </li>
        
        
        <li class="menu-item menu-item-repository">
          <a href="/repository">
            
            <i class="icon icon-project"></i>
            
            <span class="menu-title">项目</span>
          </a>
        </li>
        
        
        <li class="menu-item menu-item-books">
          <a href="/books">
            
            <i class="icon icon-book-fill"></i>
            
            <span class="menu-title">书单</span>
          </a>
        </li>
        
        
        <li class="menu-item menu-item-links">
          <a href="/links">
            
            <i class="icon icon-friendship"></i>
            
            <span class="menu-title">友链</span>
          </a>
        </li>
        
        
        <li class="menu-item menu-item-about">
          <a href="/about">
            
            <i class="icon icon-cup-fill"></i>
            
            <span class="menu-title">关于</span>
          </a>
        </li>
        
      </ul>
      
	
    <ul class="social-links">
    	
        <li><a href="https://github.com/cofess" target="_blank" title="Github" data-toggle=tooltip data-placement=top><i class="icon icon-github"></i></a></li>
        
        <li><a href="http://weibo.com/cofess" target="_blank" title="Weibo" data-toggle=tooltip data-placement=top><i class="icon icon-weibo"></i></a></li>
        
        <li><a href="https://twitter.com/iwebued" target="_blank" title="Twitter" data-toggle=tooltip data-placement=top><i class="icon icon-twitter"></i></a></li>
        
        <li><a href="https://www.behance.net/cofess" target="_blank" title="Behance" data-toggle=tooltip data-placement=top><i class="icon icon-behance"></i></a></li>
        
        <li><a href="/atom.xml" target="_blank" title="Rss" data-toggle=tooltip data-placement=top><i class="icon icon-rss"></i></a></li>
        
    </ul>

    </nav>
  </div>
</header>

  
    <aside class="sidebar" itemscope itemtype="http://schema.org/WPSideBar">
  <div class="slimContent">
    
      <div class="widget">
    <h3 class="widget-title">公告</h3>
    <div class="widget-body">
        <div id="board">
            <div class="content">
                <p>欢迎交流与分享经验!</p>
            </div>
        </div>
    </div>
</div>

    
      

    
      

    
      
    
      
  <div class="widget">
    <h3 class="widget-title">归档</h3>
    <div class="widget-body">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2022/12/">十二月 2022</a><span class="archive-list-count">3</span></li></ul>
    </div>
  </div>


    
      
  <div class="widget">
    <h3 class="widget-title">最新文章</h3>
    <div class="widget-body">
      <ul class="recent-post-list list-unstyled no-thumbnail">
        
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                
              </p>
              <p class="item-title">
                <a href="/2022/12/29/Vue%E5%85%AB%E8%82%A1%E6%96%87(31-60)/" class="title">Vue八股文31-60</a>
              </p>
              <p class="item-date">
                <time datetime="2022-12-29T06:48:08.998Z" itemprop="datePublished">2022-12-29</time>
              </p>
            </div>
          </li>
          
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                
              </p>
              <p class="item-title">
                <a href="/2022/12/26/Vue%E5%85%AB%E8%82%A1%E6%96%87(1-30)/" class="title">Vue八股文1-30</a>
              </p>
              <p class="item-date">
                <time datetime="2022-12-26T12:43:43.699Z" itemprop="datePublished">2022-12-26</time>
              </p>
            </div>
          </li>
          
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                
              </p>
              <p class="item-title">
                <a href="/2022/12/26/hello-world/" class="title">Hello World</a>
              </p>
              <p class="item-date">
                <time datetime="2022-12-26T11:23:12.435Z" itemprop="datePublished">2022-12-26</time>
              </p>
            </div>
          </li>
          
      </ul>
    </div>
  </div>
  

    
  </div>
</aside>

  
  
<main class="main" role="main">
  <div class="content">
  <article id="post-Vue八股文(1-30)" class="article article-type-post" itemscope itemtype="http://schema.org/BlogPosting">
    
    <div class="article-header">
      
        
  
    <h1 class="article-title" itemprop="name">
      Vue八股文1-30
    </h1>
  

      
      <div class="article-meta">
        <span class="article-date">
    <i class="icon icon-calendar-check"></i>
	<a href="/2022/12/26/Vue%E5%85%AB%E8%82%A1%E6%96%87(1-30)/" class="article-date">
	  <time datetime="2022-12-26T12:43:43.699Z" itemprop="datePublished">2022-12-26</time>
	</a>
</span>
        
        

        

        <span class="post-comment"><i class="icon icon-comment"></i> <a href="/2022/12/26/Vue%E5%85%AB%E8%82%A1%E6%96%87(1-30)/#comments" class="article-comment-link">评论</a></span>
        
      </div>
    </div>
    <div class="article-entry marked-body" itemprop="articleBody">
      
        <h3 id="1-你怎么理解指令？工作中你封装过自定义指令吗？举一些例子"><a href="#1-你怎么理解指令？工作中你封装过自定义指令吗？举一些例子" class="headerlink" title="1. 你怎么理解指令？工作中你封装过自定义指令吗？举一些例子"></a>1. 你怎么理解指令？工作中你封装过自定义指令吗？举一些例子</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">指令本质上是对dom的操作，vue封装这些指令就是为了我们更为合理符合规范的操作dom，避免DOM滥操作。我们也可以自定义指令，自定义指令也是对DOM操作的封装，我之前工作中封装过一些自定义指令:</span><br><span class="line">(1)防抖指令</span><br><span class="line">(2)权限指令</span><br><span class="line">......</span><br></pre></td></tr></table></figure>

<h3 id="2-计算属性能不能绑定在v-model上？"><a href="#2-计算属性能不能绑定在v-model上？" class="headerlink" title="2. 计算属性能不能绑定在v-model上？"></a>2. 计算属性能不能绑定在v-model上？</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">计算属性有setter方法时可以用v-model</span><br></pre></td></tr></table></figure>

<h3 id="3-侦听器能监听哪些变量变化？"><a href="#3-侦听器能监听哪些变量变化？" class="headerlink" title="3. 侦听器能监听哪些变量变化？"></a>3. 侦听器能监听哪些变量变化？</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">能够监听data、计算属性、vuex数据、$route等，凡是那些带有__ob__变量都能被监听到。</span><br></pre></td></tr></table></figure>

<h3 id="4-说一下Vue的响应式原理？-你是如何理解MVVM的"><a href="#4-说一下Vue的响应式原理？-你是如何理解MVVM的" class="headerlink" title="4. 说一下Vue的响应式原理？(你是如何理解MVVM的)"></a>4. 说一下Vue的响应式原理？(你是如何理解MVVM的)</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">回答版本一：</span><br><span class="line">	当vue组件被创建时，在生命周期的第一阶段，Vue使用Object.defineProperty()对data选项进行遍历劫持并添加get/set钩子；在生命周期第二阶段，指令第一次与声明式变量touch时，发生依赖收集，再调用当前组件的watcher第一次更新DOM，DOM视图就显示出来了。当声明式变量发生变化时，vue再次通知Watcher更新视图，这就是响应式（原理）</span><br><span class="line">	</span><br><span class="line">回答版本二：</span><br><span class="line">	当new Vue时，Vue源码中有一个Observer，会对data中所有的数据进行劫持，把data中的数据处理成响应式，每处理一个响应式数据，都有一个Dep与之对应。同时编译模板，编译模板时会找到小胡子语法和指令，处理小胡子语法和指令时，会创建出一个个的Watcher，这些Watcher会存储到对应的Dep中，这个过程叫依赖收集，同时调用对应的Updater，完成对应的页面的初始化。当数据发生变化时，在Observer的setter中会监听到，数据变化，就通知Dep中的Watcher更新视图，每个Watcher都绑定了更新视图的回调函数。</span><br><span class="line">	</span><br><span class="line">Vue官⽅其实有说明，Vue虽然并没有完全遵守MVVM的模型，但是整个设计是受到它的启发的。</span><br></pre></td></tr></table></figure>

<h3 id="5-你工作中有没有封装比较好的组件？"><a href="#5-你工作中有没有封装比较好的组件？" class="headerlink" title="5. 你工作中有没有封装比较好的组件？"></a>5. 你工作中有没有封装比较好的组件？</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">验证码组件等</span><br><span class="line">网上找几个别人封装的组件学习</span><br></pre></td></tr></table></figure>

<h3 id="6-说一下Vue的生命周期（展开说，不仅仅是那几个钩子）？"><a href="#6-说一下Vue的生命周期（展开说，不仅仅是那几个钩子）？" class="headerlink" title="6. 说一下Vue的生命周期（展开说，不仅仅是那几个钩子）？"></a>6. 说一下Vue的生命周期（展开说，不仅仅是那几个钩子）？</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">Vue的生命周期指的是组件从“生”到“死”的全过程，一共分四个阶段，不同阶段有不同的钩子函数：</span><br><span class="line">* 创建阶段：beforeCreate、created</span><br><span class="line">* 挂载阶段：beforeMount、mounted</span><br><span class="line">* 更新阶段：beforeUpdate、updated</span><br><span class="line">* 销毁阶段：beforeDestroy、destroyed</span><br><span class="line">* 与动态组件有关的两个特殊的钩：activated(激活)、deactivated(休眠)</span><br><span class="line">* 与组件异常捕获有关的一个钩子：errorCaptured</span><br><span class="line"></span><br><span class="line">在beforeCreate之前会声明methods中的方法和声明生命周期钩子函数，这个钩子函数我们用的并不多</span><br><span class="line"></span><br><span class="line">在created之前会注入一些数据，初始化响应式系统，我们通常在这个钩子函数中调接口，获取路由参数等</span><br><span class="line"></span><br><span class="line">在beforeMount之前会通过el $meount template找模板，会把模块变成render函数  调用render函数创建虚拟DOM，虚拟DOM转化成真实DOM，进行挂载，通常这个钩子函数我们也用不到</span><br><span class="line"></span><br><span class="line">在mounted时，已表示真实DOM已挂载完毕，我们在这个钩子中通常调接口，开定时器，DOM操作，建立websocket连接  实例化echarts实例等。</span><br><span class="line"></span><br><span class="line">当数据变化时，会触发beforeUpdate钩子，这个钩子通常也用不到。</span><br><span class="line"></span><br><span class="line">在updated之前，要生成新的虚拟DOM，新的虚拟DOM和老的虚拟DOM进行对比，会执行patch运算，diff算法，找到两个虚拟DOM的最小差异，找到后，进行异步更新，key的目的就是最快找到最小差异，这个钩子也不常用，但是有点类似于watch侦听器或类似于$nextTick()，我们不能在这个钩子中更新数据，会导致死循环。</span><br><span class="line"></span><br><span class="line">当我们手动调用$destory()或路由切换时，会调用beforeDestroy这个钩子函数，我们可以在这个钩子函数中清空定时器，解除事件绑定，清除缓存...</span><br><span class="line"></span><br><span class="line">当组件销毁时，就会移除当前组件的watcher，DOM就无法再更新，移除所有子组件，移除事件监听器，响应式系统就会失效，组件就死亡了，这个钩子函数我们用的也不多。</span><br></pre></td></tr></table></figure>

<h3 id="7-虚拟DOM存在的价值点在哪里？"><a href="#7-虚拟DOM存在的价值点在哪里？" class="headerlink" title="7. 虚拟DOM存在的价值点在哪里？"></a>7. 虚拟DOM存在的价值点在哪里？</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">把DOM更新粒度降到最低，规避人为DOM滥操作，提升性能。配合DIFF算法，可以让页面性能有质的提升。</span><br></pre></td></tr></table></figure>

<h3 id="8-Vue有哪些内置组件？Vue中实现条件渲染渲染有哪些办法？"><a href="#8-Vue有哪些内置组件？Vue中实现条件渲染渲染有哪些办法？" class="headerlink" title="8. Vue有哪些内置组件？Vue中实现条件渲染渲染有哪些办法？"></a>8. Vue有哪些内置组件？Vue中实现条件渲染渲染有哪些办法？</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">五个内置组件(slot,transition,component,keep-alive)</span><br><span class="line"></span><br><span class="line">条件渲染: v-if v-show 动态组件component的is属性</span><br></pre></td></tr></table></figure>

<h3 id="9-你有封装过Vue插件？怎么封装的？封装过什么？"><a href="#9-你有封装过Vue插件？怎么封装的？封装过什么？" class="headerlink" title="9. 你有封装过Vue插件？怎么封装的？封装过什么？"></a>9. 你有封装过Vue插件？怎么封装的？封装过什么？</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">在Vue生态中，除了Vue本身，其它所有与Vue相关的第三方包，都是插件，都得以插件的方式进行集成。</span><br><span class="line">作用：是一种更加高级的代码复用技术，可以以插件的方式为我们提供可复用的组件、混入、指令、过滤器、原型链API。</span><br><span class="line"></span><br><span class="line">两种写法：</span><br><span class="line">第一种写法： const Plugin = &#123; install (Vue) &#123; &#125; &#125;</span><br><span class="line">第二种写法： const Plugin = function (Vue) &#123;&#125;</span><br><span class="line"></span><br><span class="line">在项目中我之前二次封装axios，把它封装成一个插件，参考：</span><br><span class="line">https://juejin.cn/post/6844903599764406280</span><br><span class="line"></span><br><span class="line">封装右键菜单插件：</span><br><span class="line">https://juejin.cn/post/6906788973981466637</span><br></pre></td></tr></table></figure>

<h3 id="10-谈一谈你对-Vue-nextTick-的理解？有什么用？"><a href="#10-谈一谈你对-Vue-nextTick-的理解？有什么用？" class="headerlink" title="10. 谈一谈你对 Vue.nextTick() 的理解？有什么用？"></a>10. 谈一谈你对 Vue.nextTick() 的理解？有什么用？</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">数据变化，进行set操作，代码确实是同步的，但是set行为是异步的；set操作修改声明变量，触发re-render生成新的虚拟DOM，进一步执行diff运算，找到脏节点集合，交给Vue背后的更新队列去执行循环更新。在更新队列中每一个更新任务都是一个更新单元，nextTick表示下一个更新单元（更新周期）。</span><br><span class="line"></span><br><span class="line">我们set操作data（更新DOM），你希望访问这个DOM的最新状态时，使用this.$nextTick(handler)。</span><br></pre></td></tr></table></figure>

<h3 id="11-谈一谈Vue中组件通信？"><a href="#11-谈一谈Vue中组件通信？" class="headerlink" title="11. 谈一谈Vue中组件通信？"></a>11. 谈一谈Vue中组件通信？</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">1)父子组件通信：父传子使用自定义属性（props），子传父使用自定义事件（$emit()）。</span><br><span class="line"></span><br><span class="line">2)状态提升：当兄弟组件之间需要共享数据时，我们通常的做法是把这个数据定义它们的共同的父组件中，再通过自定义属性实现数据共享。</span><br><span class="line"></span><br><span class="line">3)provide/inject：这是在组件树中，自上而下的一种数据通信方案，也就是说只能父级组件中向后代组件传递。需要注意的是，当provide提供动态数据（声明式变量）时，动态数据发生变化，后代组件们不会自动更新。这是为什么呢？你自己从生命周期流程的角度去思考。</span><br><span class="line"></span><br><span class="line">4)ref通信：ref是Vue内置的一个属性，每一个HTML元素或组件都有这个属性；ref作用在HTML元素上得到DOM实例，ref作用在组件上得到组件实例。使用ref访问组件实例，进一步可以访问组件中的数据和方法。（说明：ref是一种快速的DOM的访问方式，当然ref也可作用在组件上得到组件实例。这些ref得到的DOM实例或组件实例，使用this.$refs来访问它们。ref尽量少用，除非某些难搞的需求。）</span><br><span class="line"></span><br><span class="line">5)插槽通信：借助&lt;slot&gt;组件实现从子组件向父组件传递数据，借助this.$slots访问父组件中的插槽实例。(在自定义组件中使用this.$slots访问父组件给的插槽实例；在父组件插槽中使用#default=&#x27;scoped&#x27;访问子组件&lt;slot&gt;回传的数据。这种通信在组件库中、工作中，非常常见！)</span><br><span class="line"></span><br><span class="line">6)$parent/$children：借助$parent/$children可以实现，在任一组件中访问组件树中的其它任意组件实例，可以做到在组件中随意穿梭。($parent表示的是当前组件的父组件实例，$children表示的是当前组件的子组件们。)</span><br><span class="line"></span><br><span class="line">7)$attrs/$listeners：借助$attrs可访问父组件传递过来的自定义属性（除了class和style外），借助$listenrs可以访问父组件给的自定义事件。在某些场景下，$attrs/$listeners可以替代props/$emit()这种通用的通信方案。</span><br><span class="line"></span><br><span class="line">8)事件总线：借助于Vue内置的事件系统（$on/$emit/$off/$once）实现“订阅-发布”式的通信，这种通信方式是一种与组件层级无关的“一对多”的通信。（工作中很少用，一些特殊的Vue项目才用得到事件总线。）</span><br><span class="line"></span><br><span class="line">9)Vuex通信：这是Vue架构中终极的通信方案，也是Vue架构中用的最多的一种通信方案。</span><br></pre></td></tr></table></figure>

<h3 id="12-Vue中逻辑复用技巧有哪些？"><a href="#12-Vue中逻辑复用技巧有哪些？" class="headerlink" title="12. Vue中逻辑复用技巧有哪些？"></a>12. Vue中逻辑复用技巧有哪些？</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">组件：复用UI+逻辑</span><br><span class="line">混入</span><br><span class="line">自定义指令</span><br><span class="line">渲染函数&amp;JSX</span><br><span class="line">插件</span><br><span class="line">过滤器</span><br><span class="line">V3中的自定义hook</span><br></pre></td></tr></table></figure>

<h3 id="13-你项目的鉴权怎么做的？你这个管理系统的权限怎么设计的？"><a href="#13-你项目的鉴权怎么做的？你这个管理系统的权限怎么设计的？" class="headerlink" title="13. 你项目的鉴权怎么做的？你这个管理系统的权限怎么设计的？"></a>13. 你项目的鉴权怎么做的？你这个管理系统的权限怎么设计的？</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">我们之前的公司中小公司，做的项目，大概有30个左右的模块，所以权限这一块，就前端去处理的。我们处理的流程大致是这样的：前端登录换取token，在导航守卫中，实现权限设计，首先判断有没有token，没有token，直接跳到登录页面。有token会进一步判断vuex中有没有用户信息。如果没有用户信息，拿着token，调用接口获取用户信息，用户信息中保存了最重要的字段，就是角色，有了角色后，通过算法生成当前用户可访问的动态路由规则（算法大至是使用后端返回的角色和路由元信息中的角色进行对比，得到可以访问的动态路由规则），有了动态访问的路由规则，再通过addRoutes方法，把得到的动态访问的路由规则添加到路由系统。</span><br></pre></td></tr></table></figure>

<h3 id="14-简述Vuex的工作流程？"><a href="#14-简述Vuex的工作流程？" class="headerlink" title="14. 简述Vuex的工作流程？"></a>14. 简述Vuex的工作流程？</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line">1.什么是vuex？</span><br><span class="line">vuex是状态管理仓库，可以实现对多个组件公共状态的集中式管理。它包含了state、getters、mutations，actions，modules五个属性。</span><br><span class="line"></span><br><span class="line">state：用于存储维护组件的公共状态,</span><br><span class="line"></span><br><span class="line">getters：用于对state中的数据进行相关处理后并返回，类似于计算属性，</span><br><span class="line"></span><br><span class="line">mutations：是修改state的唯一途径，进行的是同步操作，</span><br><span class="line"></span><br><span class="line">actions：要执行的操作，可以是同步或异步事件，</span><br><span class="line"></span><br><span class="line">modules：内部可以存放多个仓库配置对象，用于对仓库进行模块划分</span><br><span class="line"></span><br><span class="line">2.vuex的工作流程</span><br><span class="line">首先通过dispatch去提交一个actions，在actions接收到这个事件后，在actions种进行一些异步或同步操作，根据情况分发给不同的mutations，actions通过commit触发mutations，然后mutations去更新state，在state更新后，就会通知vue进行渲染。步骤如下：</span><br><span class="line"></span><br><span class="line">1.通过dispatch去提交一个actions</span><br><span class="line"></span><br><span class="line">2.在actions接收到事件后，在actions中执行一些同步或异步操作</span><br><span class="line"></span><br><span class="line">3.根据不同的情况分发给不同的mutations，actions通过commit触发mutations</span><br><span class="line"></span><br><span class="line">4.mustations在触发后就会去更新state</span><br><span class="line"></span><br><span class="line">5.在state更新完毕后，就会通知vue进行渲染</span><br><span class="line"></span><br><span class="line">5大概念：</span><br><span class="line">创建store时要用的五个概念（state/getters/mutations/actions/modules）</span><br><span class="line">- state: &#123;&#125; 用于定义可被组件共享数据，是具有响应式的；在组件中使用this.$store.state来访问它们。</span><br><span class="line">- getters: &#123;fn&#125; 用于计算state，相当于Vue的计算属性，当state发生变化时getters方法自动自动重新计算；在组件中使用this.$store.getters来访问它们。</span><br><span class="line">- mutations: &#123;fn&#125; 专门用于修改state的，所以mutations方法是这样fn(state,payload)定义的；mutations方法在actions中或组件中使用，使用$store.commit(&#x27;mutations方法&#x27;,payload)</span><br><span class="line">- actions: &#123;fn&#125; 专门用于调接口的，所以actions方法是这样fn(store,payload)定义的；在组件中使用this.$store.dispatch(&#x27;actions方法&#x27;, payload)。</span><br><span class="line">- modules: &#123;子store&#125; 是一个Vuex架构层面的概念，用于拆分子store。大家在拆分子store务必在子store中使用namespaced:true开启命名空间。</span><br><span class="line"></span><br><span class="line">4个map:</span><br><span class="line">mapState/mapGetters，必须写在computed计算属性中，用于访问state/getters数据。映射进来后，就可以用this来访问这些数据了。</span><br><span class="line">mapActions/mapMutations 必须写在methods选项中，用于访问mutations/actions方法。映射进来后，可以用this调用这些方法。</span><br><span class="line">它们的语法是相同的：map*(&#x27;命名空间&#x27;, [&#x27;k1&#x27;, &#x27;k2&#x27;])</span><br><span class="line"></span><br><span class="line">3个原则：</span><br><span class="line">原则1：只要使用Vuex一定要拆分store，拆分store后在根store上不要再使用state/mutations/actions。</span><br><span class="line">原则2：在子store务必开启命名空间namespaced:true。</span><br><span class="line">原则3：在组件中尽可能不要使用$store，建议使用四个map*方法。</span><br></pre></td></tr></table></figure>

<h3 id="15-说说你对-SPA-单⻚⾯的理解，它的优缺点分别是什么？"><a href="#15-说说你对-SPA-单⻚⾯的理解，它的优缺点分别是什么？" class="headerlink" title="15. 说说你对 SPA 单⻚⾯的理解，它的优缺点分别是什么？"></a>15. 说说你对 SPA 单⻚⾯的理解，它的优缺点分别是什么？</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">SPA（ single-page application ）仅在 Web ⻚⾯初始化时加载相应的 HTML、JavaScript 和 CSS。⼀旦</span><br><span class="line">⻚⾯加载完成，SPA 不会因为⽤户的操作⽽进⾏⻚⾯的重新加载或跳转；取⽽代之的是利⽤路由机制实现 HTML 内容的变换，UI 与⽤户的交互，避免⻚⾯的重新加载。</span><br><span class="line"></span><br><span class="line">优点：</span><br><span class="line">1)⽤户体验好、快，内容的改变不需要重新加载整个⻚⾯，避免了不必要的跳转和重复渲染；</span><br><span class="line">2)基于上⾯⼀点，SPA 相对对服务器压⼒⼩；</span><br><span class="line">3)前后端职责分离，架构清晰，前端进⾏交互逻辑，后端负责数据处理；</span><br><span class="line"></span><br><span class="line">缺点：</span><br><span class="line">1)初次加载耗时多：为实现单⻚ Web 应⽤功能及显示效果，需要在加载⻚⾯的时候将 JavaScript、CSS 统⼀加载，部分⻚⾯按需加载；</span><br><span class="line">2)前进后退路由管理：由于单⻚应⽤在⼀个⻚⾯中显示所有的内容，所以不能使⽤浏览器的前进后退功能，所有的⻚⾯切换需要⾃⼰建⽴堆栈管理；</span><br><span class="line">3)SEO 难度较⼤：由于所有的内容都在⼀个⻚⾯中动态替换显示，所以在 SEO 上其有着天然的弱势。</span><br></pre></td></tr></table></figure>

<h3 id="16-v-show-与-v-if-有什么区别？"><a href="#16-v-show-与-v-if-有什么区别？" class="headerlink" title="16.v-show 与 v-if 有什么区别？"></a>16.v-show 与 v-if 有什么区别？</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">⽤法上的区别：</span><br><span class="line">1)v-show是不⽀持template；</span><br><span class="line">2)v-show不可以和v-else⼀起使⽤；</span><br><span class="line"></span><br><span class="line">本质的区别：</span><br><span class="line">1)v-show元素⽆论是否需要显示到浏览器上，它的DOM实际都是有存在的，只是通过CSS的display属性来进⾏切换；</span><br><span class="line">2)v-if当条件为false时，其对应的原⽣压根不会被渲染到DOM中；</span><br><span class="line"></span><br><span class="line">开发中如何进⾏选择呢？</span><br><span class="line">1)如果我们的原⽣需要在显示和隐藏之间频繁的切换，那么使⽤v-show；</span><br><span class="line">2)如果不会频繁的发⽣切换，那么使⽤v-if；</span><br></pre></td></tr></table></figure>

<h3 id="17-数组中的哪些⽅法会触发视图的更新？"><a href="#17-数组中的哪些⽅法会触发视图的更新？" class="headerlink" title="17. 数组中的哪些⽅法会触发视图的更新？"></a>17. 数组中的哪些⽅法会触发视图的更新？</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">Vue 将被侦听的数组的变更⽅法进⾏了包裹，所以它们也将会触发视图更新，这些被包裹过的⽅法包括：</span><br><span class="line">1)push()</span><br><span class="line">2)pop()</span><br><span class="line">3)shift()</span><br><span class="line">4)unshift()</span><br><span class="line">5)splice()</span><br><span class="line">6)sort()</span><br><span class="line">7)reverse()</span><br><span class="line"></span><br><span class="line">上⾯的⽅法会直接修改原来的数组，所以它们会触发视图更新。但是某些⽅法不会替换原来的数组，⽽是会⽣成新的数组，⽐如 ﬁlter()、concat() 和 slice()，使⽤这些⽅法将不会触发视图更新。</span><br></pre></td></tr></table></figure>

<h3 id="18-Vue中v-for的key-有什么作⽤？"><a href="#18-Vue中v-for的key-有什么作⽤？" class="headerlink" title="18. Vue中v-for的key 有什么作⽤？"></a>18. Vue中v-for的key 有什么作⽤？</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">在使⽤v-for进⾏列表渲染时，我们通常会给元素或者组件绑定⼀个key属性。这个key属性有什么作⽤呢？</span><br><span class="line">1)key属性主要⽤在Vue的虚拟DOM算法，在新旧nodes对⽐时辨识VNodes。</span><br><span class="line">2)如果不使⽤key，Vue会使⽤⼀种最⼤限度减少动态元素并且尽可能的尝试就地修改/复⽤相同类型元素的算法</span><br><span class="line">3)使⽤key时，它会基于key的变化重新排列元素顺序，并且会移除/销毁key不存在的元素。</span><br><span class="line"></span><br><span class="line">key 是 VNode 的唯⼀标记，通过这个 key， diﬀ 操作可以更准确、更快速的达到复⽤节点，更新视图的⽬的。复⽤节点就需要通过移动元素的位置来达到更新的⽬的。</span><br></pre></td></tr></table></figure>

<h3 id="19-computed和method有什么区别？"><a href="#19-computed和method有什么区别？" class="headerlink" title="19.computed和method有什么区别？"></a>19.computed和method有什么区别？</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">计算属性和⽅法：</span><br><span class="line">1)都可以通过this来访问</span><br><span class="line">2)都可以对⼀些数据进⾏处理和计算</span><br><span class="line">3)对于包含响应式数据计算的逻辑，应该使⽤计算属性，因为计算属性是有缓存。</span><br><span class="line"></span><br><span class="line">computed和method的区别</span><br><span class="line">1)computed底层会缓存, 性能更⾼</span><br><span class="line">2)计算属性会基于它们的依赖关系进⾏缓存;</span><br><span class="line">3)在数据不发⽣变化时，计算属性是不需要重新计算的</span><br><span class="line">4)但是如果依赖的数据发⽣变化，在使⽤时，计算属性依然会重新进⾏计算</span><br></pre></td></tr></table></figure>

<h3 id="20-什么是双向绑定？v-model的本质是什么？"><a href="#20-什么是双向绑定？v-model的本质是什么？" class="headerlink" title="20. 什么是双向绑定？v-model的本质是什么？"></a>20. 什么是双向绑定？v-model的本质是什么？</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">双向绑定:</span><br><span class="line">1)即当数据发⽣变化的时候，视图也就发⽣变化，当视图发⽣变化的时候，数据也会跟着同步变化</span><br><span class="line">2)v-model 是语法糖，它负责监听⽤户在表单元素中的输⼊事件来更新数据</span><br><span class="line"></span><br><span class="line">表单元素使⽤v-model的本质：</span><br><span class="line">1)v-bind绑定value属性的值</span><br><span class="line">2)v-on绑定input事件监听到函数,函数会获取最新的值赋值到绑定的属性中</span><br><span class="line">&lt;input type=&quot;text&quot; :value=&quot;message&quot; @input=&quot;message = $event.target.value&quot; /&gt;</span><br><span class="line"></span><br><span class="line">组件使⽤v-model的本质：</span><br><span class="line">1)将其 value attribute 绑定到⼀个名叫 modelValue 的 prop 上；</span><br><span class="line">2)在其 input 事件被触发时，将新的值通过⾃定义的 update:modelValue 事件抛出(发出)；</span><br><span class="line">&lt;Counter v-model=&quot;appCounter&quot;/&gt;  &lt;!-- 相当于--&gt;</span><br><span class="line">&lt;Counter v-bind:modelValue=&quot;appCounter&quot; @update:modelValue=&quot;appCounter=$event&quot;/&gt;</span><br></pre></td></tr></table></figure>

<h3 id="21-data选项为什么是⼀个函数⽽不是对象？"><a href="#21-data选项为什么是⼀个函数⽽不是对象？" class="headerlink" title="21.data选项为什么是⼀个函数⽽不是对象？"></a>21.data选项为什么是⼀个函数⽽不是对象？</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">JavaScript中的对象是引⽤类型的数据，当多个实例引⽤同⼀个对象时，只要⼀个实例对这个对象进⾏操作，其他实例中的数据也会发⽣变化。</span><br><span class="line"></span><br><span class="line">⽽在Vue中，我们更多的是想要复⽤组件，那就需要每个组件都有⾃⼰的数据，这样组件之间才不会相互⼲扰。</span><br><span class="line">所以组件的数据不能写成对象的形式，⽽是要写成函数的形式。数据以函数返回值的形式定义。</span><br><span class="line"></span><br><span class="line">这样当我们每次复⽤组件的时候，就会返回⼀个新的data，也就是说每个组件都有⾃⼰的私有数据空间，它们各⾃维护⾃⼰的数据，不会⼲扰其他组件的正常运⾏。</span><br></pre></td></tr></table></figure>

<h3 id="22-Vue-data-中某⼀个属性的值发⽣改变后，视图会⽴即同步执⾏、重新渲染吗？"><a href="#22-Vue-data-中某⼀个属性的值发⽣改变后，视图会⽴即同步执⾏、重新渲染吗？" class="headerlink" title="22. Vue data 中某⼀个属性的值发⽣改变后，视图会⽴即同步执⾏、重新渲染吗？"></a>22. Vue data 中某⼀个属性的值发⽣改变后，视图会⽴即同步执⾏、重新渲染吗？</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">不会⽴即同步执⾏重新渲染。</span><br><span class="line"></span><br><span class="line">Vue 实现响应式并不是数据发⽣变化之后 DOM ⽴即变化，⽽是按⼀定的策略进⾏ DOM 的更新。</span><br><span class="line"></span><br><span class="line">Vue 在更新 DOM 时是异步执⾏的。只要侦听到数据变化， Vue 将开启⼀个队列，并缓冲在同⼀事件循环中发⽣的所有数据变更。</span><br><span class="line"></span><br><span class="line">如果同⼀个watcher被多次触发，只会被推⼊到队列中⼀次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是⾮常重要的。</span><br><span class="line"></span><br><span class="line">然后，在下⼀个的事件循环”tick”中，Vue 刷新队列并执⾏实际（已去重的）⼯作。</span><br></pre></td></tr></table></figure>

<h3 id="23-在-Vue-js开发环境下调⽤API接⼝，如何避免跨域"><a href="#23-在-Vue-js开发环境下调⽤API接⼝，如何避免跨域" class="headerlink" title="23. 在 Vue. js开发环境下调⽤API接⼝，如何避免跨域"></a>23. 在 Vue. js开发环境下调⽤API接⼝，如何避免跨域</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">1)在vue.conﬁg.js中的devServer选项中的proxy中配置反向代理</span><br><span class="line">2)在vite.conﬁg.js中的server选项中的proxy中配置反向代理</span><br><span class="line">3)直接后端开发⼈员配置cors</span><br></pre></td></tr></table></figure>

<h3 id="24-v-if和v-for⼀起使⽤的弊端及解决办法"><a href="#24-v-if和v-for⼀起使⽤的弊端及解决办法" class="headerlink" title="24.v-if和v-for⼀起使⽤的弊端及解决办法"></a>24.v-if和v-for⼀起使⽤的弊端及解决办法</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">Vue.js 中使⽤最多的两个指令就是 v-if 和 v-for ，因此开发者们可能会想要同时使⽤它们。虽然不建议这样做，但有时确实是必须的，于是我们想提供有关其⼯作⽅式的指南。</span><br><span class="line"></span><br><span class="line">2.x 版本中在⼀个元素上同时使⽤ v-if 和 v-for 时， v-for 会优先作⽤。</span><br><span class="line">3.x 版本中 v-if 总是优先于 v-for ⽣效。</span><br><span class="line"></span><br><span class="line">由于语法上存在歧义，建议避免在同⼀元素上同时使⽤两者。⽐起在模板层⾯管理相关逻辑，更好的办法是通过创建计算属性筛选出列表，并以此创建可⻅元素，⽐如：</span><br><span class="line">1)在v-for的外层或内层包裹⼀个元素（template）来使⽤v-if</span><br><span class="line">2)⽤computed处理筛选出列表</span><br></pre></td></tr></table></figure>

<h3 id="25-谈谈你对-keep-alive-的了解？"><a href="#25-谈谈你对-keep-alive-的了解？" class="headerlink" title="25. 谈谈你对 keep-alive 的了解？"></a>25. 谈谈你对 keep-alive 的了解？</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">keep-alive 是 Vue 内置的⼀个组件，可以使被包含的组件保留状态，避免重新渲染 ，其有以下特性：</span><br><span class="line">1)⼀般结合路由和动态组件⼀起使⽤，⽤于缓存组件。</span><br><span class="line">2)提供 include 和 exclude 属性，两者都⽀持字符串或正则表达式。include 表示只有名称匹配的组件会被缓存。exclude 表示任何名称匹配的组件都不会被缓存。其中 exclude 的优先级⽐ include ⾼。</span><br><span class="line">3)对应两个钩⼦函数 activated 和 deactivated 。当组件被激活时，触发钩⼦函数 activated。当组件被移除时，触发钩⼦函数 deactivated。</span><br></pre></td></tr></table></figure>

<h3 id="26-什么是侦听器？有什么用？"><a href="#26-什么是侦听器？有什么用？" class="headerlink" title="26. 什么是侦听器？有什么用？"></a>26. 什么是侦听器？有什么用？</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">作用：用于监听一个变量的变化，然后去做另一件事儿。</span><br><span class="line"></span><br><span class="line">特点：当侦听器监听引用数据类型时，默认只能监听引用数据类型的第一层。为什么要这样？监听深度越深，Vue在背后要做的事儿越多，这是一种性能损耗，所以一般不要对一个引用类型的变量进行深度监听。</span><br><span class="line"></span><br><span class="line">如何监听引用数据类型的每一层（深度监听）？侦听器语法这样写  info: &#123; deep: true, handler() &#123;&#125; &#125;为了避免deep:true深度监听导致性能损耗，我们推荐这种写 &#x27;info.child.age&#x27; () &#123;&#125;</span><br><span class="line"></span><br><span class="line">在Vue中，侦听器能够监听哪些性质的变量变化呢？能够监听data、计算属性、vuex数据、$route等，凡是那些带有__ob__变量都能被监听到。</span><br></pre></td></tr></table></figure>

<h3 id="27-侦听器能不能监听数组-x2F-对象的变化？"><a href="#27-侦听器能不能监听数组-x2F-对象的变化？" class="headerlink" title="27. 侦听器能不能监听数组&#x2F;对象的变化？"></a>27. 侦听器能不能监听数组&#x2F;对象的变化？</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">可以，但默认为了性能考虑，不监听深层,如果需要深层侦听，需要配置deep:true</span><br></pre></td></tr></table></figure>

<h3 id="28-如何监听一个对象中的某个属性变化？"><a href="#28-如何监听一个对象中的某个属性变化？" class="headerlink" title="28. 如何监听一个对象中的某个属性变化？"></a>28. 如何监听一个对象中的某个属性变化？</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">deep:true, 推荐 &#x27;obj.key&#x27; 这种监听写法</span><br></pre></td></tr></table></figure>

<h3 id="29-侦听器为什么默认不支持深度监听？"><a href="#29-侦听器为什么默认不支持深度监听？" class="headerlink" title="29. 侦听器为什么默认不支持深度监听？"></a>29. 侦听器为什么默认不支持深度监听？</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">性能优化</span><br></pre></td></tr></table></figure>

<h3 id="30-什么是组件化？你怎么理解组件化？"><a href="#30-什么是组件化？你怎么理解组件化？" class="headerlink" title="30. 什么是组件化？你怎么理解组件化？"></a>30. 什么是组件化？你怎么理解组件化？</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">现在主流的开发框，都是基于组件化的，组件的作用就是为了实现UI和逻辑的复用，在vue组件中，提供了很多的选项，如data,computed,watch,method,components,filter... 可以方便我们实现业务逻辑，组件化的好处就是可以复用UI和逻辑，在业务开发中，一般都会合理的划分组件，在vue中组件化的核心就是自定义属性，自定义事件，自定义插槽。</span><br><span class="line">组件与组件通信常见的有8种方案，比如：... 展开讲   如果看过源码，可以从源码角度分析组件的实现过程。</span><br></pre></td></tr></table></figure>


      
    </div>
    <div class="article-footer">
      <blockquote class="mt-2x">
  <ul class="post-copyright list-unstyled">
    
    <li class="post-copyright-link hidden-xs">
      <strong>本文链接：</strong>
      <a href="http://bear-peak.gitee.io/2022/12/26/Vue%E5%85%AB%E8%82%A1%E6%96%87(1-30)/" title="Vue八股文1-30" target="_blank" rel="external">http://bear-peak.gitee.io/2022/12/26/Vue八股文(1-30)/</a>
    </li>
    
    <li class="post-copyright-license">
      <strong>版权声明： </strong> 本博客所有文章除特别声明外，均采用 <a href="http://creativecommons.org/licenses/by/4.0/deed.zh" target="_blank" rel="external">CC BY 4.0 CN协议</a> 许可协议。转载请注明出处！
    </li>
  </ul>
</blockquote>


<div class="panel panel-default panel-badger">
  <div class="panel-body">
    <figure class="media">
      <div class="media-left">
        <a href="https://github.com/cofess" target="_blank" class="img-burn thumb-sm visible-lg">
          <img src="/images/avatar.jpg" class="img-rounded w-full" alt="">
        </a>
      </div>
      <div class="media-body">
        <h3 class="media-heading"><a href="https://github.com/cofess" target="_blank"><span class="text-dark">熊峰</span><small class="ml-1x">Web Developer &amp; Designer</small></a></h3>
        <div>个人简介。</div>
      </div>
    </figure>
  </div>
</div>


    </div>
  </article>
  
    
  <section id="comments">
  	
      <div id="vcomments"></div>
    
  </section>


  
</div>

  <nav class="bar bar-footer clearfix" data-stick-bottom>
  <div class="bar-inner">
  
  <ul class="pager pull-left">
    
    <li class="prev">
      <a href="/2022/12/29/Vue%E5%85%AB%E8%82%A1%E6%96%87(31-60)/" title="Vue八股文31-60"><i class="icon icon-angle-left" aria-hidden="true"></i><span>&nbsp;&nbsp;上一篇</span></a>
    </li>
    
    
    <li class="next">
      <a href="/2022/12/26/hello-world/" title="Hello World"><span>下一篇&nbsp;&nbsp;</span><i class="icon icon-angle-right" aria-hidden="true"></i></a>
    </li>
    
    
  </ul>
  
  
  
  <div class="bar-right">
    
    <div class="share-component" data-sites="weibo,qq,wechat,facebook,twitter" data-mobile-sites="weibo,qq,qzone"></div>
    
  </div>
  </div>
</nav>
  


</main>

  <footer class="footer" itemscope itemtype="http://schema.org/WPFooter">
	
	
    <ul class="social-links">
    	
        <li><a href="https://github.com/cofess" target="_blank" title="Github" data-toggle=tooltip data-placement=top><i class="icon icon-github"></i></a></li>
        
        <li><a href="http://weibo.com/cofess" target="_blank" title="Weibo" data-toggle=tooltip data-placement=top><i class="icon icon-weibo"></i></a></li>
        
        <li><a href="https://twitter.com/iwebued" target="_blank" title="Twitter" data-toggle=tooltip data-placement=top><i class="icon icon-twitter"></i></a></li>
        
        <li><a href="https://www.behance.net/cofess" target="_blank" title="Behance" data-toggle=tooltip data-placement=top><i class="icon icon-behance"></i></a></li>
        
        <li><a href="/atom.xml" target="_blank" title="Rss" data-toggle=tooltip data-placement=top><i class="icon icon-rss"></i></a></li>
        
    </ul>

    <div class="copyright">
    	
        <div class="publishby">
        	Theme by <a href="https://github.com/cofess" target="_blank"> cofess </a>base on <a href="https://github.com/cofess/hexo-theme-pure" target="_blank">pure</a>.
        </div>
    </div>
</footer>
  <script src="//cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
<script>
window.jQuery || document.write('<script src="js/jquery.min.js"><\/script>')
</script>

<script src="/js/plugin.min.js"></script>


<script src="/js/application.js"></script>


    <script>
(function (window) {
    var INSIGHT_CONFIG = {
        TRANSLATION: {
            POSTS: '文章',
            PAGES: '页面',
            CATEGORIES: '分类',
            TAGS: '标签',
            UNTITLED: '(未命名)',
        },
        ROOT_URL: '/',
        CONTENT_URL: '/content.json',
    };
    window.INSIGHT_CONFIG = INSIGHT_CONFIG;
})(window);
</script>

<script src="/js/insight.js"></script>






   




   
    
  <script src="//cdn1.lncld.net/static/js/3.0.4/av-min.js"></script>
  <script src="//cdn.jsdelivr.net/npm/valine"></script>
  <script type="text/javascript">
  var GUEST = ['nick', 'mail', 'link'];
  var meta = 'nick,mail,link';
  meta = meta.split(',').filter(function(item) {
    return GUEST.indexOf(item) > -1;
  });
  new Valine({
    el: '#vcomments',
    verify: false,
    notify: false,
    appId: '',
    appKey: '',
    placeholder: 'Just go go',
    avatar: 'mm',
    meta: meta,
    pageSize: '10' || 10,
    visitor: false
  });
  </script>

     







</body>
</html>